+++ /dev/null
-/* Copyright 2011, Red Hat, Inc.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU Lesser General Public License,
- * version 2.1, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope it will be useful, but WITHOUT ANY
- * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
- * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
- * more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
- */
-
-/* Login Dialog */
-
-.login-dialog-banner {
- font-size: 10pt;
- font-weight: bold;
- text-align: center;
- color: #666666;
- padding-bottom: 1em;
-}
-
-.login-dialog-title {
- font-size: 14pt;
- font-weight: bold;
- color: #666666;
- padding-bottom: 2em;
-}
-
-.login-dialog {
- border-radius: 16px;
- min-height: 150px;
- max-height: 700px;
- min-width: 350px;
-}
-
-.login-dialog-prompt-fingerprint-message {
- font-size: 10.5pt;
-}
-
-.login-dialog-user-list-view {
- -st-vfade-offset: 1em;
-}
-
-.login-dialog-user-list {
- spacing: 12px;
-}
-
-.login-dialog-user-list-item {
- color: #666666;
-}
-
-.login-dialog-user-list-item:ltr {
- padding-right: 1em;
-}
-
-.login-dialog-user-list-item:rtl {
- padding-left: 1em;
-}
-
-.login-dialog-user-list-item .login-dialog-user-list-item-name {
- font-size: 20pt;
- padding-left: 1em;
- color: #666666;
-}
-
-.login-dialog-user-list-item:hover .login-dialog-user-list-item-name {
- color: white;
-}
-
-.login-dialog-user-list-item:focus .login-dialog-user-list-item-name {
- color: white;
- text-shadow: black 0px 2px 2px;
-}
-
-.login-dialog-user-list-item-vertical-layout {
- spacing: 2px;
-}
-
-.login-dialog-user-list-item .login-dialog-user-list-item-focus-bin {
- background-color: rgba(0,0,0,0.0);
- height: 2px;
-}
-
-.login-dialog-user-list-item:focus .login-dialog-user-list-item-focus-bin {
- background-color: #666666;
-}
-
-.login-dialog-user-list-item-icon {
- border: 2px solid #8b8b8b;
- border-radius: 8px;
- width: 64px;
- height: 64px;
-}
-
-.login-dialog-not-listed-button {
- padding-top: 2em;
-}
-.login-dialog-not-listed-label {
- font-size: 14pt;
- font-weight: bold;
- color: #666666;
-}
-
-.login-dialog-not-listed-button:hover .login-dialog-not-listed-label {
- color: white;
-}
-
-.login-dialog-prompt-layout {
- padding-bottom: 32px;
-}
-.login-dialog-prompt-label {
- color: white;
- font-size: 20pt;
-}
-
-.login-dialog-prompt-entry {
- padding: 4px;
- border-radius: 4px;
- border: 2px solid #5656cc;
- color: black;
- background-color: white;
- caret-color: black;
- caret-size: 1px;
- width: 15em;
-}
-
-.login-dialog-prompt-entry .capslock-warning {
- icon-size: 16px;
- warning-color: #999;
-}
-
-.login-dialog-prompt-entry:insensitive {
- color: rgba(0,0,0,0.7);
- border: 2px solid #565656;
-}
-
-.login-dialog-session-list {
- color: #ffffff;
- font-size: 10.5pt;
-}
-
-.login-dialog-session-list-button {
- padding: 4px;
-}
-
-.login-dialog-session-list-button:focus {
- background-color: #4c4c4c;
-}
-
-.login-dialog-session-list-button:active {
- background-color: #4c4c4c;
-}
-
-.login-dialog-session-list-button:hover {
- font-weight: bold;
-}
-
-.login-dialog-session-list-scroll-view {
- background-gradient-start: rgba(80,80,80,0.3);
- background-gradient-end: rgba(80,80,80,0.7);
- background-gradient-direction: vertical;
- box-shadow: inset 0px 2px 4px rgba(0,0,0,0.9);
- border-radius: 8px;
- border: 1px solid rgba(80,80,80,1.0);
- padding: .5em;
-}
-
-.login-dialog-session-list-item:focus {
- background-color: #666666;
-}
-
-.login-dialog-session-list-triangle {
- padding-right: .5em;
-}
-
-.login-dialog-session-list-item-box {
- spacing: .25em;
-}
-
-.login-dialog-session-list-item-dot {
- width: .75em;
- height: .75em;
-}
border-radius: 4px;
background-color: rgba(255,255,255,0.33);
}
+
+/* Login Dialog */
+
+.login-dialog-banner {
+ font-size: 10pt;
+ font-weight: bold;
+ text-align: center;
+ color: #666666;
+ padding-bottom: 1em;
+}
+
+.login-dialog-title {
+ font-size: 14pt;
+ font-weight: bold;
+ color: #666666;
+ padding-bottom: 2em;
+}
+
+.login-dialog {
+ border-radius: 16px;
+ min-height: 150px;
+ max-height: 700px;
+ min-width: 350px;
+}
+
+.login-dialog-prompt-fingerprint-message {
+ font-size: 10.5pt;
+}
+
+.login-dialog-user-list-view {
+ -st-vfade-offset: 1em;
+}
+
+.login-dialog-user-list {
+ spacing: 12px;
+}
+
+.login-dialog-user-list-item {
+ color: #666666;
+}
+
+.login-dialog-user-list-item:ltr {
+ padding-right: 1em;
+}
+
+.login-dialog-user-list-item:rtl {
+ padding-left: 1em;
+}
+
+.login-dialog-user-list-item .login-dialog-user-list-item-name {
+ font-size: 20pt;
+ padding-left: 1em;
+ color: #666666;
+}
+
+.login-dialog-user-list-item:hover .login-dialog-user-list-item-name {
+ color: white;
+}
+
+.login-dialog-user-list-item:focus .login-dialog-user-list-item-name {
+ color: white;
+ text-shadow: black 0px 2px 2px;
+}
+
+.login-dialog-user-list-item-vertical-layout {
+ spacing: 2px;
+}
+
+.login-dialog-user-list-item .login-dialog-user-list-item-focus-bin {
+ background-color: rgba(0,0,0,0.0);
+ height: 2px;
+}
+
+.login-dialog-user-list-item:focus .login-dialog-user-list-item-focus-bin {
+ background-color: #666666;
+}
+
+.login-dialog-user-list-item-icon {
+ border: 2px solid #8b8b8b;
+ border-radius: 8px;
+ width: 64px;
+ height: 64px;
+}
+
+.login-dialog-not-listed-label {
+ font-size: 14pt;
+ font-weight: bold;
+ color: #666666;
+}
+
+.login-dialog-not-listed-button:hover .login-dialog-not-listed-label {
+ color: #E8E8E8;
+}
+
+.login-dialog-prompt-layout {
+ padding-bottom: 32px;
+}
+.login-dialog-prompt-label {
+ color: white;
+ font-size: 20pt;
+}
+
+.login-dialog-prompt-entry {
+ padding: 4px;
+ border-radius: 4px;
+ border: 2px solid #5656cc;
+ color: black;
+ background-color: white;
+ caret-color: black;
+ caret-size: 1px;
+ width: 15em;
+}
+
+.login-dialog-prompt-entry .capslock-warning {
+ icon-size: 16px;
+ warning-color: #999;
+}
+
+.login-dialog-prompt-entry:insensitive {
+ color: rgba(0,0,0,0.7);
+ border: 2px solid #565656;
+}
+
+.login-dialog-session-list {
+ color: #ffffff;
+ font-size: 10.5pt;
+}
+
+.login-dialog-session-list-button {
+ padding: 4px;
+}
+
+.login-dialog-session-list-button:focus {
+ background-color: #4c4c4c;
+}
+
+.login-dialog-session-list-button:active {
+ background-color: #4c4c4c;
+}
+
+.login-dialog-session-list-button:hover {
+ font-weight: bold;
+}
+
+.login-dialog-session-list-scroll-view {
+ background-gradient-start: rgba(80,80,80,0.3);
+ background-gradient-end: rgba(80,80,80,0.7);
+ background-gradient-direction: vertical;
+ box-shadow: inset 0px 2px 4px rgba(0,0,0,0.9);
+ border-radius: 8px;
+ border: 1px solid rgba(80,80,80,1.0);
+ padding: .5em;
+}
+
+.login-dialog-session-list-item:focus {
+ background-color: #666666;
+}
+
+.login-dialog-session-list-triangle {
+ padding-right: .5em;
+}
+
+.login-dialog-session-list-item-box {
+ spacing: .25em;
+}
+
+.login-dialog-session-list-item-dot {
+ width: .75em;
+ height: .75em;
+}
+
+.unlock-dialog-user-name {
+ padding: 4px;
+ border-radius: 4px;
+ border: 2px solid #5656cc;
+ color: black;
+ background-color: white;
+ caret-color: black;
+ caret-size: 1px;
+ width: 15em;
+ text-align: right;
+}
+
+.unlock-dialog-user-name-container {
+ spacing: .4em;
+}
ui/status/bluetooth.js \
ui/telepathyClient.js \
ui/tweener.js \
+ ui/unlockDialog.js \
ui/userMenu.js \
ui/viewSelector.js \
ui/wanda.js \
const GnomeSession = imports.misc.gnomeSession;
const Lightbox = imports.ui.lightbox;
-const LoginDialog = imports.gdm.loginDialog;
+const UnlockDialog = imports.ui.unlockDialog;
const Main = imports.ui.main;
const SCREENSAVER_SCHEMA = 'org.gnome.desktop.screensaver';
let constraint = new Clutter.BindConstraint({ source: global.stage,
coordinate: Clutter.BindCoordinate.POSITION | Clutter.BindCoordinate.SIZE });
this._group.add_constraint(constraint);
- this._group.connect('key-press-event', Lang.bind(this, this._onKeyPressEvent));
- this._group.connect('button-press-event', Lang.bind(this, this._onButtonPressEvent));
+
this._lightbox = new Lightbox.Lightbox(this._group,
{ inhibitEvents: true, fadeInTime: 10, fadeFactor: 1 });
this._background = Meta.BackgroundActor.new_for_screen(global.screen);
if (lightboxWasShown && this._settings.get_boolean(LOCK_ENABLED_KEY)) {
this._background.show();
this._background.raise_top();
+
+ this._showUnlockDialog();
} else {
this._popModal();
}
this._background.hide();
},
- _onKeyPressEvent: function(object, keyPressEvent) {
- log("in _onKeyPressEvent - lock is enabled: " + this._settings.get_boolean(LOCK_ENABLED_KEY));
- this._popModal();
+ _showUnlockDialog: function() {
+ if (this._dialog)
+ return;
+
+ this._dialog = new UnlockDialog.UnlockDialog();
+ this._dialog.connect('failed', Lang.bind(this, this._onUnlockFailed));
+ this._dialog.connect('unlocked', Lang.bind(this, this._onUnlockSucceded));
+
+ this._dialog.open(global.get_current_time());
},
- _onButtonPressEvent: function(object, buttonPressEvent) {
- log("in _onButtonPressEvent - lock is enabled: " + this._settings.get_boolean(LOCK_ENABLED_KEY));
+ _onUnlockFailed: function() {
+ // for now, on failure we just destroy the dialog and create a new
+ // one (this is what gnome-screensaver does)
+ // in the future, we may want to go back to the lock screen instead
+
+ this._dialog.destroy();
+ this._dialog = null;
+
+ this._showUnlockDialog();
+ },
+
+ _onUnlockSucceded: function() {
+ this._dialog.destroy();
+ this._dialog = null;
+
this._popModal();
},
});
hasRunDialog: false,
hasWorkspaces: false,
createSession: Main.createGDMSession,
- extraStylesheet: global.datadir + '/theme/gdm.css',
+ extraStylesheet: null,
statusArea: {
order: [
'a11y', 'display', 'keyboard',
--- /dev/null
+// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
+
+const AccountsService = imports.gi.AccountsService;
+const Clutter = imports.gi.Clutter;
+const Gdm = imports.gi.Gdm;
+const Gio = imports.gi.Gio;
+const GLib = imports.gi.GLib;
+const Gtk = imports.gi.Gtk;
+const Lang = imports.lang;
+const Mainloop = imports.mainloop;
+const Signals = imports.signals;
+const Shell = imports.gi.Shell;
+const St = imports.gi.St;
+
+const Main = imports.ui.main;
+const ModalDialog = imports.ui.modalDialog;
+const ShellEntry = imports.ui.shellEntry;
+const Tweener = imports.ui.tweener;
+const UserMenu = imports.ui.userMenu;
+
+const Batch = imports.gdm.batch;
+const GdmUtil = imports.gdm.util;
+
+// A widget showing the user avatar and name
+const UserWidget = new Lang.Class({
+ Name: 'UserWidget',
+
+ _init: function(user) {
+ this._user = user;
+
+ this.actor = new St.BoxLayout({ style_class: 'unlock-dialog-user-name-container',
+ vertical: false });
+
+ this._avatar = new UserMenu.UserAvatarWidget(user);
+ this.actor.add(this._avatar.actor,
+ { x_fill: true, y_fill: true });
+
+ this._label = new St.Label({ style_class: 'unlock-dialog-user-name' });
+ this.actor.add(this._label,
+ { expand: true,
+ x_fill: true,
+ y_fill: true });
+
+ this._userLoadedId = this._user.connect('notify::is-loaded',
+ Lang.bind(this, this._updateUser));
+ this._userChangedId = this._user.connect('changed',
+ Lang.bind(this, this._updateUser));
+ if (this._user.is_loaded)
+ this._updateUser();
+ },
+
+ destroy: function() {
+ if (this._userLoadedId != 0) {
+ this._user.disconnect(this._userLoadedId);
+ this._userLoadedId = 0;
+ }
+
+ if (this._userChangedId != 0) {
+ this._user.disconnect(this._userChangedId);
+ this._userChangedId = 0;
+ }
+
+ this.actor.destroy();
+ },
+
+ _updateUser: function() {
+ if (this._user.is_loaded)
+ this._label.text = this._user.get_real_name();
+ else
+ this._label.text = '';
+
+ this._avatar.update();
+ }
+});
+
+const UnlockDialog = new Lang.Class({
+ Name: 'UnlockDialog',
+ Extends: ModalDialog.ModalDialog,
+
+ _init: function() {
+ this.parent({ shellReactive: true,
+ styleClass: 'login-dialog' });
+
+ this._userManager = AccountsService.UserManager.get_default();
+ this._userName = GLib.get_user_name();
+ this._user = this._userManager.get_user(this._userName);
+
+ this._greeterClient = new Gdm.Client();
+ this._userVerifier = new GdmUtil.ShellUserVerifier(this._greeterClient);
+
+ this._userVerifier.connect('reset', Lang.bind(this, this._reset));
+ this._userVerifier.connect('ask-question', Lang.bind(this, this._onAskQuestion));
+ this._userVerifier.connect('verification-complete', Lang.bind(this, this._onVerificationComplete));
+ this._userVerifier.connect('verification-failed', Lang.bind(this, this._onVerificationFailed));
+
+ this._userVerifier.connect('show-fingerprint-prompt', Lang.bind(this, this._showFingerprintPrompt));
+ this._userVerifier.connect('hide-fingerprint-prompt', Lang.bind(this, this._hideFingerprintPrompt));
+
+ this._userWidget = new UserWidget(this._user);
+ this.contentLayout.add_actor(this._userWidget.actor);
+
+ this._promptLayout = new St.BoxLayout({ style_class: 'login-dialog-prompt-layout',
+ vertical: false });
+
+ this._promptLabel = new St.Label({ style_class: 'login-dialog-prompt-label' });
+ this._promptLayout.add(this._promptLabel,
+ { expand: false,
+ x_fill: true,
+ y_fill: true,
+ x_align: St.Align.START });
+
+ this._promptEntry = new St.Entry({ style_class: 'login-dialog-prompt-entry',
+ can_focus: true });
+ ShellEntry.addContextMenu(this._promptEntry);
+ this.setInitialKeyFocus(this._promptEntry);
+ this._promptEntry.clutter_text.connect('activate', Lang.bind(this, this._doUnlock));
+
+ this._promptLayout.add(this._promptEntry,
+ { expand: true,
+ x_fill: true,
+ y_fill: false,
+ x_align: St.Align.START });
+
+ this.contentLayout.add_actor(this._promptLayout);
+
+ // Translators: this message is shown below the password entry field
+ // to indicate the user can swipe their finger instead
+ this._promptFingerprintMessage = new St.Label({ text: _("(or swipe finger)"),
+ style_class: 'login-dialog-prompt-fingerprint-message' });
+ this._promptFingerprintMessage.hide();
+ this.contentLayout.add_actor(this._promptFingerprintMessage);
+
+ let otherUserLabel = new St.Label({ text: _("Login as another user"),
+ style_class: 'login-dialog-not-listed-label' });
+ this._otherUserButton = new St.Button({ style_class: 'login-dialog-not-listed-button',
+ can_focus: true,
+ child: otherUserLabel,
+ reactive: true,
+ x_align: St.Align.START,
+ x_fill: true });
+ this._otherUserButton.connect('clicked', Lang.bind(this, this._otherUserClicked));
+ this.contentLayout.add(this._otherUserButton,
+ { x_align: St.Align.START,
+ x_fill: false });
+
+ this._okButton = { label: _("Unlock"),
+ action: Lang.bind(this, this._doUnlock),
+ default: true };
+ this.setButtons([this._okButton]);
+
+ this._updateOkButton(false);
+ this._reset();
+ },
+
+ _updateOkButton: function(sensitive) {
+ this._okButton.button.reactive = sensitive;
+ },
+
+ _reset: function() {
+ this._userVerifier.begin(this._userName, new Batch.Hold());
+ },
+
+ _onAskQuestion: function(verifier, serviceName, question, passwordChar) {
+ this._promptLabel.text = question;
+
+ this._promptEntry.text = '';
+ this._promptEntry.clutter_text.set_password_char(passwordChar);
+ this._promptEntry.menu.isPassword = passwordChar != '';
+
+ this._currentQuery = serviceName;
+ this._updateOkButton(true);
+ },
+
+ _showFingerprintPrompt: function() {
+ GdmUtil.fadeInActor(this._promptFingerprintMessage);
+ },
+
+ _hideFingerprintPrompt: function() {
+ GdmUtil.fadeOutActor(this._promptFingerprintMessage);
+ },
+
+ _doUnlock: function() {
+ if (!this._currentQuery)
+ return;
+
+ let query = this._currentQuery;
+ this._currentQuery = null;
+
+ this._updateOkButton(false);
+
+ this._userVerifier.answerQuery(query, this._promptEntry.text);
+ },
+
+ _onVerificationComplete: function() {
+ this._userVerifier.clear();
+ this.emit('unlocked');
+ },
+
+ _onVerificationFailed: function() {
+ this._userVerifier.cancel();
+ this.emit('failed');
+ },
+
+ _otherUserClicked: function(button, event) {
+ this._userManager.goto_login_session();
+
+ this._userVerifier.cancel();
+ this.emit('failed');
+ },
+
+ destroy: function() {
+ this._userVerifier.clear();
+ this.parent();
+ },
+
+ cancel: function() {
+ this._userVerifier.cancel(null);
+
+ this.destroy();
+ },
+});